﻿//-----------------------------------------------------------------------
// <copyright file="DynamicSetting.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
//-----------------------------------------------------------------------
#region Usings
using System;
using System.Collections.Generic;
using FastNET.CleanAct.Common.Repository;
using FastNET.CleanAct.Common.Repository.Business;
using FastNET.CleanAct.Common.Repository.Interfaces.DataInterfaces.Client;
using FastNET.CleanAct.Common.Repository.Interfaces.Factories;
using FastNET.CleanAct.Common.Repository.Interfaces.Repositories.Client;
#endregion

namespace FastNET.CleanAct.Client.CleanEngineBusiness
{
    /// <summary>
    /// Business Class representing a dynamic setting for the client
    /// </summary>
    public class DynamicSetting : IdentityBusinessBase<IDynamicSettingData, IDynamicSettingRepository>
    {
        #region Variables

        private UserProfile __profile;

        #endregion

        #region Public CTor/DTor

        /// <summary>
        /// Initializes a new instance of the DynamicSetting class
        /// </summary>
        public DynamicSetting()
            : this(new RepositoryFactory())
        {
        }

        /// <summary>
        /// Initializes a new instance of the DynamicSetting class
        /// </summary>
        /// <param name="ID">Identity of the data to retrieve</param>
        public DynamicSetting(Identity ID)
            : this(new RepositoryFactory(), ID)
        {
        }

        #endregion

        #region Internal CTor/DTor

        /// <summary>
        /// Initializes a new instance of the DynamicSetting class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <param name="data">Data for backing the business object</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory or Data are null</exception>
        internal DynamicSetting(IRepositoryFactory factory, IDynamicSettingData data)
            : base(factory, data)
        {
        }

        /// <summary>
        /// Initializes a new instance of the DynamicSetting class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory is null</exception>
        internal DynamicSetting(IRepositoryFactory factory)
            : base(factory)
        {
        }

        /// <summary>
        /// Initializes a new instance of the DynamicSetting class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <param name="ID">Identity of the data to retrieve</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory is null</exception>
        internal DynamicSetting(IRepositoryFactory factory, Identity ID)
            : base(factory, ID)
        {
        }

        #endregion

        #region Overrides of BusinessBase<IDynamicSettingData,IDynamicSettingRepository>

        /// <summary>
        /// Method to check whether or not the current object is valid
        /// </summary>
        /// <returns>Boolean based on the validity of the object</returns>
        public override bool IsValid()
        {
            return true;
        }

        #endregion

        #region Lazy Loaded Properties

        /// <summary>
        /// Gets a reference to the User Profile
        /// </summary>
        public UserProfile Profile
        {
            get
            {
                if (__profile == null && Data.ProfileID.HasValue)
                {
                    __profile = new UserProfile(Factory, Data.ProfileID.Value);
                }

                return __profile;
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the key identifier for the setting
        /// </summary>
        public string KeyName
        {
            get
            {
                return Data.KeyName;
            }

            set
            {
                Data.KeyName = value;
            }
        }

        /// <summary>
        /// Gets or sets the value for the setting
        /// </summary>
        public string Value
        {
            get
            {
                return Data.Value;
            }

            set
            {
                Data.Value = value;
            }
        }

        /// <summary>
        /// Gets or sets the associated profile ID
        /// </summary>
        public Identity? ProfileID
        {
            get
            {
                return Data.ProfileID;
            }

            set
            {
                Data.ProfileID = value;
                __profile = null;
            }
        }

        #endregion

        #region Internal Static Factory Methods

        /// <summary>
        /// Retrieves all settings associated with a key name
        /// </summary>
        /// <param name="factory">RepositoryFactory to retrieve the data from</param>
        /// <param name="keyName">Key of the settings to retrieve</param>
        /// <returns>List of DynamicSetting found</returns>
        internal static List<DynamicSetting> RetrieveByKeyName(IRepositoryFactory factory, string keyName)
        {
            List<DynamicSetting> returnValue = new List<DynamicSetting>();
            IList<IDynamicSettingData> retrievedList = factory.GetRepository<IDynamicSettingRepository>().RetrieveByKeyName(keyName);

            foreach (IDynamicSettingData data in retrievedList)
            {
                returnValue.Add(new DynamicSetting(factory, data));
            }

            return returnValue;
        }

        /// <summary>
        /// Retrieves all settings associated with a profile
        /// </summary>
        /// <param name="factory">RepositoryFactory to retrieve the data from</param>
        /// <param name="profileID">Profile of the setting group to retrieve or null for the global settings</param>
        /// <returns>List of DynamicSetting found</returns>
        internal static List<DynamicSetting> RetrieveByProfileID(IRepositoryFactory factory, Identity? profileID)
        {
            List<DynamicSetting> returnValue = new List<DynamicSetting>();
            IList<IDynamicSettingData> retrievedList = factory.GetRepository<IDynamicSettingRepository>().RetrieveByProfileID(profileID);

            foreach (IDynamicSettingData data in retrievedList)
            {
                returnValue.Add(new DynamicSetting(factory, data));
            }

            return returnValue;
        }

        /// <summary>
        /// Retrieves a single setting using the profile ID and the key name
        /// </summary>
        /// <param name="factory">RepositoryFactory to retrieve the data from</param>
        /// <param name="profileID">Profile of the setting group to retrieve or null for the global settings</param>
        /// <param name="keyName">Key of the setting to retrieve</param>
        /// <returns>DynamicSetting found or null if the setting does not exist</returns>
        internal static DynamicSetting RetrieveByProfileAndKey(IRepositoryFactory factory, Identity? profileID, string keyName)
        {
            IDynamicSettingData data = factory.GetRepository<IDynamicSettingRepository>().RetrieveByProfileAndKey(profileID, keyName);
            return data == null ? null : new DynamicSetting(factory, data);
        }

        #endregion

        #region Public Static Factory Methods

        /// <summary>
        /// Retrieves all settings associated with a key name
        /// </summary>
        /// <param name="keyName">Key of the settings to retrieve</param>
        /// <returns>List of DynamicSetting found</returns>
        public static List<DynamicSetting> RetrieveByKeyName(string keyName)
        {
            return RetrieveByKeyName(new RepositoryFactory(), keyName);
        }

        /// <summary>
        /// Retrieves all settings associated with a profile
        /// </summary>
        /// <param name="profileID">Profile of the setting group to retrieve or null for the global settings</param>
        /// <returns>List of DynamicSetting found</returns>
        public static List<DynamicSetting> RetrieveByProfileID(Identity? profileID)
        {
            return RetrieveByProfileID(new RepositoryFactory(), profileID);
        }

        /// <summary>
        /// Retrieves a single setting using the profile ID and the key name
        /// </summary>
        /// <param name="profileID">Profile of the setting group to retrieve or null for the global settings</param>
        /// <param name="keyName">Key of the setting to retrieve</param>
        /// <returns>DynamicSetting found or null if the setting does not exist</returns>
        public static DynamicSetting RetrieveByProfileAndKey(Identity? profileID, string keyName)
        {
            return RetrieveByProfileAndKey(new RepositoryFactory(), profileID, keyName);
        }

        #endregion
    }
}
